load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("//bazel:defs.bzl", "file_size_check")
load("//publish:defs.bzl", "artifact_bundle")
load("//rs/nns:nns.bzl", NNS_CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES = "CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES")
load("//rs/sns:sns.bzl", SNS_CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES = "CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES")

# The list of canisters that are being published/uploaded as artifacts to our CDN (download.dfinity.systems) include
# 1. Officially released canisters that can be downloaded/verified by 3rd parties - https://github.com/dfinity/ic/blob/master/.github/workflows/tag-release.yml
# 2. Mainnet canisters - https://github.com/dfinity/ic/blob/master/mainnet-canisters.bzl
# 3. Canisters required for dfx - https://github.com/dfinity/dfx-extensions/tree/main/extensions-utils/src/dependencies/download_wasms
# 4. Canisters required for test environments.
CANISTERS = {
    "canister-creator-canister.wasm.gz": "//rs/rust_canisters/canister_creator:canister_creator_canister",
    "load_simulator_canister.wasm.gz": "//rs/rust_canisters/load_simulator:load_simulator_canister",
    "cycles-minting-canister.wasm.gz": "//rs/nns/cmc:cycles-minting-canister",
    "genesis-token-canister.wasm.gz": "//rs/nns/gtc:genesis-token-canister",
    "governance-canister.wasm.gz": "//rs/nns/governance:governance-canister",
    "governance-canister_test.wasm.gz": "//rs/nns/governance:governance-canister-test",
    "ic-btc-checker.wasm.gz": "//rs/bitcoin/checker:btc_checker_canister",
    "ic-ckbtc-minter.wasm.gz": "//rs/bitcoin/ckbtc/minter:ckbtc_minter",
    "ic-ckbtc-minter_debug.wasm.gz": "//rs/bitcoin/ckbtc/minter:ckbtc_minter_debug",
    "ic-ckdoge-minter.wasm.gz": "//rs/dogecoin/ckdoge/minter:ckdoge_minter",
    "ic-ckdoge-minter_debug.wasm.gz": "//rs/dogecoin/ckdoge/minter:ckdoge_minter_debug",
    "ic-cketh-minter.wasm.gz": "//rs/ethereum/cketh/minter:cketh_minter",
    "ic-icrc1-archive.wasm.gz": "//rs/ledger_suite/icrc1/archive:archive_canister",
    "ic-icrc1-archive-u256.wasm.gz": "//rs/ledger_suite/icrc1/archive:archive_canister_u256",
    "ic-icrc1-index-ng.wasm.gz": "//rs/ledger_suite/icrc1/index-ng:index_ng_canister",
    "ic-icrc1-index-ng-u256.wasm.gz": "//rs/ledger_suite/icrc1/index-ng:index_ng_canister_u256",
    "ic-icrc1-ledger.wasm.gz": "//rs/ledger_suite/icrc1/ledger:ledger_canister",
    "ic-icrc1-ledger-u256.wasm.gz": "//rs/ledger_suite/icrc1/ledger:ledger_canister_u256",
    "ic-icp-index-canister.wasm.gz": "//rs/ledger_suite/icp/index:ic-icp-index-canister",
    "ic-ledger-suite-orchestrator-canister.wasm.gz": "//rs/ethereum/ledger-suite-orchestrator:ledger_suite_orchestrator_canister",
    "identity-canister.wasm.gz": "//rs/nns/identity:identity-canister",
    "ledger-archive-node-canister.wasm.gz": "//rs/ledger_suite/icp/archive:ledger-archive-node-canister-wasm",
    "ledger-canister.wasm.gz": "//rs/ledger_suite/icp/ledger:ledger-canister-wasm",
    # FIXME(FI-1845): Remove once all users have migrated to the ledger canister without notify-method in the name.
    "ledger-canister_notify-method.wasm.gz": "//rs/ledger_suite/icp/ledger:ledger-canister-wasm",
    "lifeline_canister.wasm.gz": "//rs/nns/handlers/lifeline/impl:lifeline_canister",
    "migration-canister.wasm.gz": "//rs/migration_canister:migration-canister",
    "nns-ui-canister.wasm.gz": "//rs/nns/nns-ui:nns-ui-canister",
    "rate-limit-canister.wasm.gz": "//rs/boundary_node/rate_limits:rate_limit_canister",
    "registry-canister.wasm.gz": "//rs/registry/canister:registry-canister",
    "root-canister.wasm.gz": "//rs/nns/handlers/root/impl:root-canister",
    "salt-sharing-canister.wasm.gz": "//rs/boundary_node/salt_sharing:salt_sharing_canister",
    "sns-governance-canister.wasm.gz": "//rs/sns/governance:sns-governance-canister",
    "sns-governance-canister_test.wasm.gz": "//rs/sns/governance:sns-governance-canister-test",
    "sns-root-canister.wasm.gz": "//rs/sns/root:sns-root-canister",
    "sns-swap-canister.wasm.gz": "//rs/sns/swap:sns-swap-canister",
    "sns-wasm-canister.wasm.gz": "//rs/nns/sns-wasm:sns-wasm-canister",
    # Needed by DRE team for qualification
    "xnet-test-canister.wasm.gz": "//rs/rust_canisters/xnet_test:xnet-test-canister",
    # Used in snsdemo repo for NNS dapp test environment
    "bitcoin-mock-canister.wasm.gz": "//rs/bitcoin/mock:bitcoin_canister_mock",

    # Boundary Nodes
    "certificate-orchestrator.wasm.gz": "//rs/boundary_node/certificate_issuance/certificate_orchestrator:certificate_orchestrator",

    # Node Rewards
    "node-rewards-canister.wasm.gz": "//rs/node_rewards/canister:node-rewards-canister",
    "node-rewards-canister-test.wasm.gz": "//rs/node_rewards/canister:node-rewards-canister-test",

    # Helpful in advanced testing scenarios, e.g., to emulate a broken 3rd party canister.
    "universal_canister.wasm.gz": "//rs/universal_canister/impl:universal_canister",
}

COMPRESSED_CANISTERS = {
    "ic-btc-canister.wasm.gz": "@btc_canister//file",
}

DEFAULT_CANISTERS_MAX_SIZE_E5_BYTES = 21

CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES = {
    # -- FI team --
    # The compressed version of these two canisters should be ~700kb,
    # we are setting the check to 8 to leave some space for growth
    # but enough to get an alert in case of a spike in size.
    # The size is currently at 701737 bytes.
    "ic-icrc1-ledger.wasm.gz": 8,
    # The size is currently at 704585 bytes.
    "ic-icrc1-ledger-u256.wasm.gz": 8,
    # Size when constraint addded: 901_184 bytes
    "ledger-canister.wasm.gz": 10,
    # Size when constraint addded: 906_940 bytes
    "ledger-canister_notify-method.wasm.gz": 10,

    # -- XC team --
    # Size when constraint addded: 447_593 bytes
    "ic-btc-checker.wasm.gz": 6,
    # Size when constraint addded: 802_894 bytes
    "ic-ckbtc-minter.wasm.gz": 9,
    # Size when constraint addded: 1_230_630 bytes
    "ic-cketh-minter.wasm.gz": 13,
    # The orchestrator needs to embed 3 wasms at compile time
    # (ICRC1 index, ICRC1 ledger, and ICRC1 archive) and size is
    # therefore strictly controlled.
    # Size when constraint addded: 1_704_979 bytes
    "ic-ledger-suite-orchestrator-canister.wasm.gz": 18,

    # -- BN team --
    # Size when constraint addded: 540_349 bytes
    "rate-limit-canister.wasm.gz": 7,
    # Size when constraint addded: 452_227 bytes
    "salt-sharing-canister.wasm.gz": 6,
}

CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.update(NNS_CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES)

CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.update(SNS_CANISTER_NAME_TO_MAX_COMPRESSED_WASM_SIZE_E5_BYTES)

[
    file_size_check(
        name = file + "_size_check",
        file = file,
        max_file_size = CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.get(
            file,
            DEFAULT_CANISTERS_MAX_SIZE_E5_BYTES,
        ) * 100000,
    )
    for (file, size) in CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES.items()
]

# `bazel cquery --output=files` that is used by build-ic script does not show external sources of `filegroup` targets.
[
    copy_file(
        name = "copy_" + compressed_file_name,
        src = target,
        out = compressed_file_name,
    )
    for (compressed_file_name, target) in CANISTERS.items() + COMPRESSED_CANISTERS.items()
    if compressed_file_name.endswith(".wasm.gz")
]

filegroup(
    name = "canisters",
    srcs = [name for name in CANISTERS] +
           [name for name in COMPRESSED_CANISTERS],
)

# Export checksums & build artifacts
artifact_bundle(
    name = "bundle",
    testonly = True,
    inputs = [":canisters"] + [":canisters.did"],
    prefix = "canisters",
    visibility = ["//visibility:public"],
)

# the further targets are all testonly for simplicity because if a target was
# violating the testonly flag, it would error at this point

[
    copy_file(
        name = name + "-did",
        testonly = True,
        src = target + ".didfile",
        out = name + ".did",
        allow_symlink = False,
    )
    for (name, target) in CANISTERS.items()
    if (
        name.endswith(".wasm.gz")
    )
]

filegroup(
    name = "canisters.did",
    testonly = True,
    srcs = [
        n + "-did"
        for n, t in CANISTERS.items()
        if (
            n.endswith(".wasm.gz")
        )
    ],
)
